package com.barneyx.mshinfoplatform.util.admin;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.barneyx.mshinfoplatform.entity.admin.*;
import com.barneyx.mshinfoplatform.entity.area.AreaEntity;
import com.barneyx.mshinfoplatform.entity.common.DefaultSettingConfig;
import com.barneyx.mshinfoplatform.entity.enums.EUserState;
import com.barneyx.mshinfoplatform.exception.AdminUserException;
import com.barneyx.mshinfoplatform.service.admin.*;
import com.barneyx.mshinfoplatform.service.area.IAreaEntityService;
import com.barneyx.mshinfoplatform.util.EventUtil;
import com.barneyx.mshinfoplatform.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

import static com.barneyx.mshinfoplatform.entity.enums.EEventType.EVENT_ADMIN_LOGIN_SUCCESS;

@Service
@Slf4j
public class AdminUtil {

    @Resource
    public IAdminUserEntityService adminUserService;

    @Resource
    public IAdminUserRoleMapEntityService adminUserRoleMapService;

    @Resource
    public IAdminRoleEntityService adminRoleService;

    @Resource
    public IAdminRolePermissionMapEntityService adminRolePermissionMapService;

    @Resource
    public IAdminPermissionEntityService adminPermissionService;

    @Resource
    public IAreaAdminUserMapEntityService areaAdminUserMapService;

    @Resource
    private IAreaEntityService areaService;

    @Resource
    private RedisUtil redisUtil;
    @Resource
    private EventUtil eventUtil;


    /**
     * 根据当前用户编号获取当前用户所管辖的区域列表
     *
     * @param adminUserId
     * @return
     * @throws AdminUserException
     */
    public List<AreaEntity> getAreaAdminListByAdminUserId(String adminUserId) {
        List<AreaAdminUserMapEntity> list = areaAdminUserMapService.list(new LambdaQueryWrapper<AreaAdminUserMapEntity>().eq(AreaAdminUserMapEntity::getUserId, adminUserId));

        if (list == null || list.isEmpty()) return null;
        List<String> areaIds = list.stream().map(AreaAdminUserMapEntity::getAreaId).collect(Collectors.toList());
        List<AreaEntity> area_list = areaService.list(new LambdaQueryWrapper<AreaEntity>().in(AreaEntity::getAreaId, areaIds));
        area_list.forEach(areaEntity -> {
            if (!areaEntity.getAreaParentId().equals("0"))
                areaEntity.setParentAreaInfo(areaService.getById(areaEntity.getAreaParentId()));
        });
        return area_list;
    }





    public boolean createAreaAdminMapData(List<AreaAdminUserMapEntity> areaadminUserList) {
        areaAdminUserMapService.deleteAdminAreaMapByAdminUserId(Long.parseLong(areaadminUserList.get(0).getUserId()));
        return areaAdminUserMapService.saveBatch(areaadminUserList);
    }


    /**
     * 删除指定的用户和地区映射
     *
     * @param areadId
     * @param adminUserId
     * @return
     */
    public void deleteUserAreaMapById(String areadId, String adminUserId) {
        areaAdminUserMapService.deleteAdminAreaMapByAdminUserIdAndAreaId(adminUserId, areadId);

    }


    /**
     * 创建管理员
     *
     * @param adminUser
     * @return
     * @throws AdminUserException
     */
    public AdminUserEntity createAdminUser(AdminUserEntity adminUser) throws AdminUserException {
        long count = adminUserService.count(new LambdaQueryWrapper<AdminUserEntity>().eq(AdminUserEntity::getUserName, adminUser.getUserName().trim()));
        long emailcount = adminUserService.count(new LambdaQueryWrapper<AdminUserEntity>().eq(AdminUserEntity::getUserEmail, adminUser.getUserEmail().trim()));

        if (emailcount > 0)
            throw new AdminUserException(StrUtil.format("当前用户{}已经存在,无法创建!", adminUser.getUserEmail()));

        if (count > 0)
            throw new AdminUserException(StrUtil.format("当前用户{}已经存在,无法创建相同名称的用户名称的管理员信息", adminUser.getUserName()));
        boolean save = adminUserService.save(adminUser);
        return save ? adminUser : null;
    }


    @Transactional
    public AdminUserEntity updateAdminUserInfo(AdminUserEntity adminUser) throws AdminUserException {
        long count = adminUserService.count(new LambdaQueryWrapper<AdminUserEntity>()
                .eq(AdminUserEntity::getUserEmail, adminUser.getUserEmail().trim())
                .eq(AdminUserEntity::getUserName, adminUser.getUserName().trim())
                .ne(AdminUserEntity::getAdminId, adminUser.getAdminId()));
        if (count > 0) throw new AdminUserException("您修改的内容和系统中某些字段重复！请检查！");
        boolean update = adminUserService.update(new LambdaUpdateWrapper<AdminUserEntity>()
                .eq(AdminUserEntity::getAdminId, adminUser.getAdminId())
                .set(AdminUserEntity::getUserPwd, adminUser.getUserPwd()));

        return update ? adminUser : null;
    }


    public boolean deleteAdminUserByUserId(String adminUserId) throws AdminUserException {
        AdminUserEntity adminUser = adminUserService.getById(adminUserId);
        if (adminUser.getIsSys()) throw new AdminUserException("系统级选项开启！无法删除！请关闭此账号的系统级选项再试！");
        //清空此用户的分组映射数据
        adminUserRoleMapService.deleteMapInfoByAdminUserId(adminUserId);
        //清空此用户的地区控制映射数据
        areaAdminUserMapService.deleteAdminAreaMapByAdminUserId(adminUserId);
        return true;
    }

    /**
     * 用户登陆
     *
     * @param userName
     * @param userPwd
     * @return
     * @throws AdminUserException
     */
    public AdminUserEntity login(String userName, String userPwd, String LoginDvice, boolean fullInfo) throws AdminUserException {
        if (StrUtil.isAllBlank(userName.trim(), userPwd)) throw new AdminUserException("用户名或是密码不能为空");
        AdminUserEntity admin_user = adminUserService.getOne(new LambdaQueryWrapper<AdminUserEntity>()
                .allEq(MapUtil.builder(new HashMap<SFunction<AdminUserEntity, ?>, Object>())
                        .put(AdminUserEntity::getUserName, userName.trim())
                        .put(AdminUserEntity::getUserPwd, userPwd)
                        .build()));
        if (admin_user == null) throw new AdminUserException("您的用户名或是密码有误,请检查后重新登陆");
        if (admin_user.getUserState() == EUserState.LOCK)
            throw new AdminUserException("当前用户已锁定,无法使用,请联系管理员了解详情");
        if (admin_user.getUserState() == EUserState.BLACKLIST)
            throw new AdminUserException("当前用户在黑名单当中,无法使用,请联系管理员了解详情");
        //填充其他信息

        if (fullInfo) {
            admin_user.setRoles(getAdminUserRolesByAdminUserId(admin_user.getAdminId()));
            admin_user.setPermissions(getUserPermissionListByUserId(admin_user.getAdminId()));
            admin_user.setControllerAreas(getAreaAdminListByAdminUserId(admin_user.getAdminId()));
            admin_user.fullInfoStrInfo();
        }
        StpUtil.login(admin_user.getAdminId(), LoginDvice);
        redisUtil.set(StrUtil.format("MSH_ADMIN_LOGIN_{}", admin_user.getAdminId()), JSONUtil.toJsonStr(admin_user));
        eventUtil.AdminManageEvent(EVENT_ADMIN_LOGIN_SUCCESS, admin_user);
        return admin_user;
    }


    /**
     * 获取指定用户的分组列表信息
     *
     * @param adminUserId
     * @return
     * @throws AdminUserException
     */
    public List<AdminRoleEntity> getAdminUserRolesByAdminUserId(String adminUserId) {
        List<AdminUserRoleMapEntity> role_user_map_list = adminUserRoleMapService.list(new LambdaQueryWrapper<AdminUserRoleMapEntity>()
                .eq(AdminUserRoleMapEntity::getAdminUserId, adminUserId));
        if (role_user_map_list == null || role_user_map_list.isEmpty()) return null;
        List<String> role_ids = role_user_map_list.stream().map(AdminUserRoleMapEntity::getRoleId).collect(Collectors.toList());
        return adminRoleService.list(new LambdaQueryWrapper<AdminRoleEntity>().in(AdminRoleEntity::getRoleId, role_ids));
    }

    /**
     * 通过指定的分组Id获取当前分组下面的所有用户
     *
     * @param adminRoidId
     * @return
     * @throws AdminUserException
     */
    public List<AdminRoleEntity> getAdminUserRolesByAdminRoleId(String adminRoidId) {
        List<AdminUserRoleMapEntity> role_user_map_list = adminUserRoleMapService.list(new LambdaQueryWrapper<AdminUserRoleMapEntity>()
                .eq(AdminUserRoleMapEntity::getRoleId, adminRoidId));
        if (role_user_map_list == null || role_user_map_list.isEmpty()) return null;
        List<String> role_ids = role_user_map_list.stream().map(AdminUserRoleMapEntity::getRoleId).collect(Collectors.toList());
        return adminRoleService.list(new LambdaQueryWrapper<AdminRoleEntity>().in(AdminRoleEntity::getRoleId, role_ids));
    }

    /**
     * 获取指定的分组列表的组代码表
     *
     * @param roles
     * @return
     */
    public List<String> getRoleCodeList(List<AdminRoleEntity> roles) {
        if (roles == null || roles.isEmpty()) return null;
        return roles.stream().map(AdminRoleEntity::getRoleCode).collect(Collectors.toList());
    }

    /**
     * 获取指定的分组列表Ids
     *
     * @param roles
     * @return
     */
    public List<String> getRoleIdList(List<AdminRoleEntity> roles) {
        if (roles == null || roles.isEmpty()) return null;
        return roles.stream().map(AdminRoleEntity::getRoleId).collect(Collectors.toList());
    }


    /**
     * 通过指定的分组编号Id查询当前分组下面的所有权限列表
     *
     * @param roleId
     * @return
     */
    public List<AdminPermissionEntity> getRolePermissionByRoleId(String roleId) {
        List<AdminRolePermissionMapEntity> role_permission_map_list = adminRolePermissionMapService.list(new LambdaQueryWrapper<AdminRolePermissionMapEntity>().eq(AdminRolePermissionMapEntity::getRoleId, roleId));
        if (role_permission_map_list == null || role_permission_map_list.isEmpty()) return null;
        List<String> permission_ids = role_permission_map_list.stream().map(AdminRolePermissionMapEntity::getPermissionId).collect(Collectors.toList());
        return adminPermissionService.list(new LambdaQueryWrapper<AdminPermissionEntity>().in(AdminPermissionEntity::getPermissionId, permission_ids));
    }

    /**
     * 通过数组的Role Ids列表获取权限列表
     *
     * @param roleId
     * @return
     */
  /*  public List<AdminPermissionEntity> getRolePermissionByRoleIds(String... roleId) {
        List<AdminRolePermissionMapEntity> role_permission_map_list = adminRolePermissionMapService.list(new LambdaQueryWrapper<AdminRolePermissionMapEntity>().in(AdminRolePermissionMapEntity::getRoleId, roleId));
        if (role_permission_map_list == null || role_permission_map_list.isEmpty()) return null;
        List<String> permission_ids = role_permission_map_list.stream().map(AdminRolePermissionMapEntity::getPermissionId).collect(Collectors.toList());
        return adminPermissionService.list(new LambdaQueryWrapper<AdminPermissionEntity>().in(AdminPermissionEntity::getPermissionId, permission_ids));
    }*/
    public List<AdminPermissionEntity> getRolePermissionByRoleIds(List<String> roleIds) {
        List<AdminRolePermissionMapEntity> role_permission_map_list = adminRolePermissionMapService.list(new LambdaQueryWrapper<AdminRolePermissionMapEntity>().in(AdminRolePermissionMapEntity::getRoleId, roleIds));
        if (role_permission_map_list == null || role_permission_map_list.isEmpty()) return null;
        List<String> permission_ids = role_permission_map_list.stream().map(AdminRolePermissionMapEntity::getPermissionId).collect(Collectors.toList());
        return adminPermissionService.list(new LambdaQueryWrapper<AdminPermissionEntity>().in(AdminPermissionEntity::getPermissionId, permission_ids));
    }

    /**
     * 通过数组的Role Ids列表获取权限列表
     *
     * @param roles
     * @return
     */
    public List<AdminPermissionEntity> getRolePermissionByRoleList(List<AdminRoleEntity> roles) {
        List<String> role_ids = roles.stream().map(AdminRoleEntity::getRoleId).collect(Collectors.toList());
        List<AdminRolePermissionMapEntity> role_permission_map_list = adminRolePermissionMapService.list(new LambdaQueryWrapper<AdminRolePermissionMapEntity>().in(AdminRolePermissionMapEntity::getRoleId, role_ids));
        if (role_permission_map_list == null || role_permission_map_list.isEmpty()) return null;
        List<String> permission_ids = role_permission_map_list.stream().map(AdminRolePermissionMapEntity::getPermissionId).collect(Collectors.toList());
        return adminPermissionService.list(new LambdaQueryWrapper<AdminPermissionEntity>().in(AdminPermissionEntity::getPermissionId, permission_ids));
    }

    /**
     * 获取指定列表的权限列表的权限代码List
     *
     * @param adminPermissionEntities
     * @return
     */
    public List<String> getPermissionList2PermissionCodeList(List<AdminPermissionEntity> adminPermissionEntities) {
        if (adminPermissionEntities == null || adminPermissionEntities.isEmpty()) return null;
        return adminPermissionEntities.stream().map(AdminPermissionEntity::getPermissionCode).collect(Collectors.toList());
    }


    /**
     * 通过用户编号获取当前用户的权限列表
     *
     * @param UserId
     * @return
     * @throws AdminUserException
     */
    public List<AdminPermissionEntity> getUserPermissionListByUserId(String UserId) throws AdminUserException {
        List<AdminRoleEntity> adminUserRoles = getAdminUserRolesByAdminUserId(UserId);
        List<String> roleIdList = getRoleIdList(adminUserRoles);
        if (roleIdList == null || roleIdList.isEmpty()) return null;
        return getRolePermissionByRoleIds(roleIdList);
    }

    /**
     * 通过分组Id获取当前分组所属的所有权限列表
     *
     * @param roleId
     * @return
     * @throws AdminUserException
     */

    public List<AdminPermissionEntity> getUserPermissionListByRoleId(String roleId) throws AdminUserException {
        List<AdminRoleEntity> adminUserRoles = getAdminUserRolesByAdminRoleId(roleId);
        List<String> roleIdList = getRoleIdList(adminUserRoles);
        if (roleIdList == null || roleIdList.isEmpty()) return null;
        return getRolePermissionByRoleIds(roleIdList);
    }


    public List<AdminRoleEntity> getRoles() {
        List<AdminRoleEntity> roles = adminRoleService.list();
        roles.forEach(role -> {
            List<AdminPermissionEntity> permission = getRolePermissionByRoleId(role.getRoleId());
            if (permission != null && !permission.isEmpty()) role.setPermissionEntityList(permission);
        });
        return roles;
    }

    public AdminRoleEntity getRoleById(String RoleId) {
        return adminRoleService.getById(RoleId);
    }

    public AdminRoleEntity updateRoleById(AdminRoleEntity roleData) throws AdminUserException {
        long count = adminRoleService.count(new LambdaQueryWrapper<AdminRoleEntity>().eq(AdminRoleEntity::getRoleCode, roleData.getRoleCode())
                .eq(AdminRoleEntity::getRoleName, roleData.getRoleName())
                .ne(AdminRoleEntity::getRoleId, roleData.getRoleId()));
        if (count > 0) throw new AdminUserException("当前系统中已经存在此名称的分组,无法修改!!!!!!");
        return adminRoleService.updateById(roleData) ? roleData : null;
    }

    public AdminRoleEntity createRole(AdminRoleEntity roleData) throws AdminUserException {
        long count = adminRoleService.count(new LambdaQueryWrapper<AdminRoleEntity>().eq(AdminRoleEntity::getRoleCode, roleData.getRoleCode())
                .eq(AdminRoleEntity::getRoleName, roleData.getRoleName()));
        if (count > 0) throw new AdminUserException("错误,当前系统中已经存在相同名称的分组,无法创建相同名称的分组");
        return adminRoleService.save(roleData) ? roleData : null;
    }

    /**
     * 删除指定的分组
     *
     * @param roleId
     * @return
     * @throws AdminUserException
     */
    public boolean deleteAdminRoleById(Serializable roleId) throws AdminUserException {
        return adminRoleService.deleteRoleById(roleId);
    }


    /////////////////////////////////////////权限////////////////////

    /**
     * 获取所有权限
     *
     * @return
     */
    public List<AdminPermissionEntity> getPermissionList() {
        return adminPermissionService.list();
    }

    public List<AdminPermissionEntity> getPermissionLevel2() {
        return adminPermissionService.list(new LambdaQueryWrapper<AdminPermissionEntity>().in(AdminPermissionEntity::getPermissionLevel, 1, 2));
    }

    /**
     * 创建新的权限条目
     *
     * @param permission
     * @return
     * @throws AdminUserException
     */
    public AdminPermissionEntity createPermission(AdminPermissionEntity permission) throws AdminUserException {
        if (StrUtil.isAllBlank(permission.getPermissionName(), permission.getPermissionCode(), permission.getPermissionCateCode()))
            throw new AdminUserException("您的权限昵称,权限代码,权限分组代码其中一项没有填写,请填写后重试");
        //判断是否有同代码的权限条目
        long count = adminPermissionService.count(new LambdaQueryWrapper<AdminPermissionEntity>().eq(AdminPermissionEntity::getPermissionCode, permission.getPermissionCode()));
        if (count > 0) throw new AdminUserException("当前系统中,存在类型的权限条目,无法添加相同的权限条目");
        return adminPermissionService.save(permission) ? permission : null;
    }

    /**
     * 修改权限
     *
     * @param permission
     * @return
     * @throws AdminUserException
     */
    public AdminPermissionEntity updatePermissionById(AdminPermissionEntity permission) throws AdminUserException {
        if (StrUtil.isAllBlank(permission.getPermissionName(), permission.getPermissionCode(), permission.getPermissionCateCode()))
            throw new AdminUserException("您的权限昵称,权限代码,权限分组代码其中一项没有填写,请填写后重试");
        long count = adminPermissionService.count(new LambdaQueryWrapper<AdminPermissionEntity>()
                .eq(AdminPermissionEntity::getPermissionCode, permission.getPermissionCode())
                .ne(AdminPermissionEntity::getPermissionId, permission.getPermissionId()));
        if (count > 0) throw new AdminUserException("修改失败,当前系统权限条目中有此条目!!!");
        return adminPermissionService.updateById(permission) ? permission : null;
    }


    public AdminPermissionEntity getPermissionById(String permissionId) {
        return adminPermissionService.getById(permissionId);
    }


    /**
     * 删除指定的权限条目
     *
     * @param permissionId
     * @return
     */
    public boolean deletePermissionById(String permissionId) {
        return adminPermissionService.removeById(permissionId);
    }


    /**
     * 获取指定的分组下面的所有权限列表
     *
     * @param roleId
     * @return
     */
    public List<String> getPermissionByRoleId(String roleId) {
        List<AdminRolePermissionMapEntity> list = adminRolePermissionMapService.list(new LambdaQueryWrapper<AdminRolePermissionMapEntity>()
                .eq(AdminRolePermissionMapEntity::getRoleId, roleId));
        if (list == null || list.isEmpty()) return null;
        return list.stream().map(AdminRolePermissionMapEntity::getPermissionId).collect(Collectors.toList());
    }

    /**
     * 删除指定的分组下面的所有权限
     *
     * @param roleId
     * @return
     */
    public boolean deleteRolePermissionMapDataByRoleId(String roleId) {
        return adminRolePermissionMapService.deleteRolePermissionMapByRoleId(roleId) >= 0;
    }


    /**
     * 创建指定的分组id的权限映射信息
     *
     * @param roleId
     * @param permissoins
     * @return
     * @throws AdminUserException
     */
    public boolean createRolePermissionMapDataByRoleId(String roleId, List<String> permissoins) throws AdminUserException {
        if (StrUtil.isBlank(roleId)) throw new AdminUserException("创建失败,您创建的分组编号不能为空,请重新尝试");
        List<AdminRolePermissionMapEntity> map_data = new ArrayList<>();
        if (permissoins == null || permissoins.isEmpty())
            throw new AdminUserException("操作失败,当前创建的权限列表为空!");
        deleteRolePermissionMapDataByRoleId(roleId);
        permissoins.forEach(id -> {
            map_data.add(AdminRolePermissionMapEntity.builder()
                    .PermissionId(id)
                    .RoleId(roleId)
                    .build());
        });

        return adminRolePermissionMapService.saveBatch(map_data);
    }

}
